﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using Cloak.NUnit;
using Cloak.Reflection;
using NUnit.Framework;
using Ruleweaver.Rules;

namespace Ruleweaver.Conditions.Schemas
{
	public class GetDeclaredConditionsForMethodWithParameters : Behavior
	{
		private DeclaredConditionSource _source;
		private IEnumerable<Condition> _conditions;

		protected override void Given()
		{
			_source = new MethodConditionSource();
		}

		protected override void When()
		{
			_conditions = _source.GetConditions();
		}

		[Then]
		public void NoConditionsDeclared()
		{
			Assert.IsFalse(_conditions.Any());
		}

		private sealed class TargetType
		{
			public void GetTarget(int parameter)
			{}
		}

		private sealed class MethodConditionSource : DeclaredConditionSource
		{
			public override Type TargetType
			{
				get { return typeof(TargetType); }
			}

			protected override IEnumerable<IConditionDeclaration> GetDeclarations(MemberInfo member)
			{
				// Methods with parameters cannot serve as check methods - the declaration should not be used, resulting in an empty set of conditions

				if(member.DeclaringType != typeof(object))
				{
					yield return new TestDeclaration();
				}
			}
		}

		private sealed class TestDeclaration : IConditionDeclaration
		{
			public IEnumerable<Condition> GetConditions(Type targetType)
			{
				var method = Reflect.Func<ICheckable<int>, Check<int>>(Checkable.IsPositive);

				yield return new Condition(Rule.Check(method), typeof(int));
			}
		}
	}
}